package com.cema.manage.project.android.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.response.AlipayFundTransUniTransferResponse;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.cema.manage.common.exception.BizException;
import com.cema.manage.project.android.model.PageVo;
import com.cema.manage.project.android.model.WithdrawalRecordVo;
import com.cema.manage.project.android.service.BizWithdrawalService;
import com.cema.manage.project.enums.MoneyTypeEnum;
import com.cema.manage.project.enums.RedisEnum;
import com.cema.manage.project.enums.ToExamineEnum;
import com.cema.manage.project.enums.UserEffectiveStatusEnum;
import com.cema.manage.project.manage.adRecord.domain.AdRecord;
import com.cema.manage.project.manage.adRecord.service.IAdRecordService;
import com.cema.manage.project.manage.users.domain.Users;
import com.cema.manage.project.manage.users.service.IUsersService;
import com.cema.manage.project.manage.withdrawalConfig.domain.WithdrawalConfig;
import com.cema.manage.project.manage.withdrawalConfig.service.IWithdrawalConfigService;
import com.cema.manage.project.manage.withdrawalRecord.domain.WithdrawalRecord;
import com.cema.manage.project.manage.withdrawalRecord.mapper.WithdrawalRecordMapper;
import com.cema.manage.project.manage.withdrawalRecord.service.IWithdrawalRecordService;
import com.cema.manage.project.util.DateUtils;
import com.cema.manage.redis.RedisService;
import com.cema.manage.zfb.AlipayFundTransUniTService;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

import static com.cema.manage.project.enums.MoneyTypeEnum.MONEY_COMMISSION_GOLD_COINS;

/**
 * @author Administrator
 */
@Service
public class BizWithdrawalServiceImpl implements BizWithdrawalService {
    @Resource
    private IWithdrawalConfigService withdrawalConfigService;

    @Resource
    private IWithdrawalRecordService withdrawalRecordService;

    @Resource
    private WithdrawalRecordMapper withdrawalRecordMapper;

    @Resource
    private AlipayFundTransUniTService alipayFundTransUniTService;

    @Resource
    private RedisService redisService;

    @Resource
    private IUsersService usersService;

    @Resource
    private IAdRecordService adRecordService;

    private final ReentrantLock lock = new ReentrantLock();

    @Override
    public List<WithdrawalConfig> queryWithdrawalConfig(String type, String uvChannel) {
        EntityWrapper<WithdrawalConfig> entityWrapper = new EntityWrapper<>();
        WithdrawalConfig withdrawalConfig = new WithdrawalConfig();
        withdrawalConfig.setWcType(Integer.parseInt(type));
        withdrawalConfig.setUvChannel(Integer.parseInt(uvChannel));
        entityWrapper.setEntity(withdrawalConfig);
        return withdrawalConfigService.selectList(entityWrapper);
    }

    @Override
    public boolean userWithdrawal(Users users, WithdrawalRecordVo recordVo) throws AlipayApiException {
        lock.lock();
        try {
            users = usersService.selectById(users.getId());
            //验证是否有提现权限
            EntityWrapper<AdRecord> adRecordEntityWrapper = new EntityWrapper<>();
            adRecordEntityWrapper.eq("us_id", users.getId());
            // 设置查询条件
            DateUtils.getCurrentDayTime(adRecordEntityWrapper, "create_time");
            int count = adRecordService.selectCount(adRecordEntityWrapper);
            int number = Integer.parseInt((String) redisService.get(RedisEnum.WITHDRAWAL_NUMBER.getKey() + recordVo.getUvChannel()));
            //佣金提现无需看广告
            if (MoneyTypeEnum.MONEY_COMMISSION_GOLD_COINS.getValue().equals(recordVo.getType())
                    || MoneyTypeEnum.MONEY_COMMISSION_RED_ENVELOPE.getValue().equals(recordVo.getType())
                    || MoneyTypeEnum.MONEY_EXTENSION_RED_ENVELOPE.getValue().equals(recordVo.getType())
            ) {
                number = 0;
            }
            if (count < number) {
                throw new BizException("请先看完" + number + "条广告，再来提现");
            }
            WithdrawalConfig withdrawalConfig = withdrawalConfigService.selectById(recordVo.getId());
            //提现金额验证
            if (ObjectUtil.isNull(withdrawalConfig)) {
                throw new BizException("无效金额");
            }
            if (!recordVo.getWcMoney().equals(withdrawalConfig.getWcMoney())) {
                throw new BizException("无效金额");
            }
            Integer type = recordVo.getType();
            Double money = withdrawalConfig.getWcMoney() * 10000;
            Integer wrMoney = users.getMoneyGoldCoin();
            if (type.equals(MoneyTypeEnum.MONEY_RED_ENVELOPE.getValue())) {
                wrMoney = users.getMoneyRedPacket();
            }
            if (type.equals(MoneyTypeEnum.MONEY_COMMISSION_GOLD_COINS.getValue())) {
                wrMoney = users.getMoneyCommissionGoldCoin();
            }
            if (type.equals(MoneyTypeEnum.MONEY_COMMISSION_RED_ENVELOPE.getValue())) {
                wrMoney = users.getMoneyCommissionRedEnvelope();
            }
            if (type.equals(MoneyTypeEnum.MONEY_EXTENSION_RED_ENVELOPE.getValue())) {
                wrMoney = users.getMoneyExtensionRedEnvelope();
            }
            if (wrMoney < money.intValue()) {
                throw new BizException("无效金额");
            }

            //提现次数
            EntityWrapper<WithdrawalRecord> recordEntityWrapper = new EntityWrapper<>();
            recordEntityWrapper.eq("wc_id", recordVo.getId());
            recordEntityWrapper.eq("us_id", users.getId());
            DateUtils.getCurrentDayTime(recordEntityWrapper, "create_time");
            int countRecord = withdrawalRecordService.selectCount(recordEntityWrapper);
            if (countRecord >= withdrawalConfig.getWcNumber()) {
                throw new BizException("当前" + withdrawalConfig.getWcMoney() + "元一天只能提现" + withdrawalConfig.getWcNumber() + "次");
            }
            WithdrawalRecord withdrawalRecord = new WithdrawalRecord();
            String order = RandomUtil.randomNumbers(20);
            //验证是否无需审核直接打款
            String withdrawalWhiteList = (String) redisService.get(RedisEnum.WITHDRAWAL_WHITE_LIST.getKey() + recordVo.getUvChannel());
            if (withdrawalConfig.getWsToExamine().equals(ToExamineEnum.TO_EXAMINE_RED_ENVELOPE.getValue())
                    ||(StrUtil.isNotEmpty(withdrawalWhiteList) && withdrawalWhiteList.contains(String.valueOf(users.getId())))){
                AlipayFundTransUniTransferResponse transferResponse = alipayFundTransUniTService.alipaySingle(users, order, String.valueOf(withdrawalConfig.getWcMoney()), "活动" + recordVo.getType(), recordVo.getUvChannel());
                if (transferResponse.isSuccess()) {
                    withdrawalRecord.setWrStatus(ToExamineEnum.TO_EXAMINE_RED_ENVELOPE.getValue());
                    withdrawalRecord.setWrPayOrderId(transferResponse.getPayFundOrderId());
                    withdrawalRecord.setUpdateTime(new Date());
                    Integer parentId = users.getUsParentId();
                    //验证有邀请人
                    if (ObjectUtil.isNotNull(parentId) && UserEffectiveStatusEnum.USER_EFFECTIVE_STATUS_VIOLATION.getValue().equals(users.getEffective())) {
                        users.setEffective(UserEffectiveStatusEnum.USER_EFFECTIVE_STATUS_NORMAL.getValue());
                        usersService.updateMoneyExtensionRedEnvelope(parentId, money.intValue(),recordVo.getUvChannel());
                    }
                } else {
                    withdrawalRecord.setWrMark(transferResponse.getSubMsg());
                    withdrawalRecord.setWrStatus(ToExamineEnum.TO_EXAMINE_GOLD_COINS.getValue());
                }
            }
            withdrawalRecord.setWrBeforeMoney(wrMoney);
            withdrawalRecord.setWrAfterMoney(wrMoney - money.intValue());
            withdrawalRecord.setWrMoney(money.intValue());
            withdrawalRecord.setUsId(users.getId());
            withdrawalRecord.setWrOrderId(order);
            withdrawalRecord.setUsNickname(users.getNickname());
            withdrawalRecord.setWrName(users.getAfbName());
            withdrawalRecord.setWrPhone(users.getAfbPhone());
            withdrawalRecord.setWrChannel(recordVo.getChannel());
            withdrawalRecord.setWrType(recordVo.getType());
            withdrawalRecord.setWcId(recordVo.getId());
            withdrawalRecord.setUvChannel(recordVo.getUvChannel());
            withdrawalRecord.setWrDurationOfUse(recordVo.getWrDurationOfUse());
            withdrawalRecordService.insert(withdrawalRecord);
            //用户操作
            Users usersUpdate = new Users();
            if (type.equals(MoneyTypeEnum.MONEY_GOLD_COINS.getValue())) {
                users.setMoneyGoldCoin(withdrawalRecord.getWrAfterMoney());
                usersUpdate.setMoneyGoldCoin(withdrawalRecord.getWrAfterMoney());
            }
            if (type.equals(MoneyTypeEnum.MONEY_RED_ENVELOPE.getValue())) {
                users.setMoneyRedPacket(withdrawalRecord.getWrAfterMoney());
                usersUpdate.setMoneyRedPacket(withdrawalRecord.getWrAfterMoney());
            }
            if (type.equals(MONEY_COMMISSION_GOLD_COINS.getValue())) {
                users.setMoneyCommissionGoldCoin(withdrawalRecord.getWrAfterMoney());
                usersUpdate.setMoneyCommissionGoldCoin(withdrawalRecord.getWrAfterMoney());
            }
            if (type.equals(MoneyTypeEnum.MONEY_COMMISSION_RED_ENVELOPE.getValue())) {
                users.setMoneyCommissionRedEnvelope(withdrawalRecord.getWrAfterMoney());
                usersUpdate.setMoneyCommissionRedEnvelope(withdrawalRecord.getWrAfterMoney());
            }
            if (type.equals(MoneyTypeEnum.MONEY_EXTENSION_RED_ENVELOPE.getValue())) {
                users.setMoneyExtensionRedEnvelope(withdrawalRecord.getWrAfterMoney());
                usersUpdate.setMoneyExtensionRedEnvelope(withdrawalRecord.getWrAfterMoney());
            }
            usersUpdate.setId(users.getId());
            usersUpdate.setEffective(users.getEffective());
            redisService.set(users.getOpenid() + users.getDeviceId(), users);
            return usersService.updateById(usersUpdate);
        } finally {
            lock.unlock();
        }
    }

    @Override
    public List<WithdrawalRecord> getUserWithdrawla(Integer userId, PageVo pageVo) {
        String current = pageVo.getCurrent();
        String size = pageVo.getSize();
        int sizeC = Integer.parseInt(size);
        int pageSize = (Integer.parseInt(current) - 1) * sizeC;
        RowBounds rowBounds = new RowBounds(pageSize, sizeC);
        EntityWrapper<WithdrawalRecord> entityWrapper = new EntityWrapper<>();
        entityWrapper.eq("us_id", userId);
        entityWrapper.eq("wr_type", pageVo.getQueryValue());
        entityWrapper.orderBy("create_time", false);
        return withdrawalRecordMapper.selectPage(rowBounds, entityWrapper);
    }

}
